/* process.c */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "process.h"
#include "log.h"
#include "ticket.h"
#include "user.h"

int order_no;
ticket_collection_t * tickets;
user_database_t * users;
logfile_t *logfile;

static int login(protocol_t *in_msg, protocol_t* out_msg);
static int query_ticket(protocol_t *in_msg, protocol_t* out_msg);
static int book_ticket(protocol_t *in_msg, protocol_t* out_msg);
static int query_booking(protocol_t *in_msg, protocol_t* out_msg);
static int end_session(protocol_t *in_msg, protocol_t* out_msg);

static business_handler process_handlers[10] = {
	NULL,
	login,
	NULL,
	book_ticket,
	NULL,
	query_ticket,
	NULL,
	query_booking,
	NULL,
	end_session
};
	
int process_action(protocol_t *in_msg, protocol_t *out_msg){
	if(in_msg->act_type <=0 || in_msg->act_type>9)
		return -1;
	else if(process_handlers[in_msg->act_type] == NULL) 
		return -1;

	return process_handlers[in_msg->act_type](in_msg, out_msg);
}

int tbs_init(){
	order_no = 0;
	if( tickets == NULL){
		if((tickets = ticket_collection_open("data/ticket.dat")) == NULL){
			perror("cannot open ticket database!");
			exit(-1);
		}
	}
	
	if( users == NULL){
		if((users = user_database_open("data/user.dat")) == NULL){
			perror("cannot open user database!");
			exit(-1);
		}
	}
	
	if( logfile == NULL){
		if((logfile = logfile_open("data/logs.log")) == NULL){
			perror("cannot open log file!");
			exit(-1);
		}
	}
	return 0;
}

int tbs_end(){
	return 0;
}




static int login(protocol_t *in_msg, protocol_t* out_msg){
	int id;
	if(in_msg == NULL || out_msg == NULL ||in_msg->act_type != ASK_LOGIN)
		return -1;
	out_msg->act_type = RPL_LOGIN;
	strcpy(out_msg->usr_name, in_msg->usr_name);
	strcpy(out_msg->usr_pwd, in_msg->usr_pwd);
	
	id = check_user(users, in_msg->usr_name, in_msg->usr_pwd);
	if(id >= -3){
		out_msg->usr_id = id;
		return 0;
	}else 
		return -1;
}

static int query_ticket(protocol_t *in_msg, protocol_t* out_msg){
	if(in_msg == NULL || out_msg == NULL ||in_msg->act_type != ASK_QUERY_TICKET)
		return -1;
	if(in_msg->usr_id < 0){
		out_msg->act_type = RPL_DENY;
		return 0;
	}
	return 0;
}

static int book_ticket(protocol_t *in_msg, protocol_t* out_msg){
	int i;
	ticket_t * tics = tickets->tickets;
	if(in_msg == NULL || out_msg == NULL ||in_msg->act_type != ASK_BOOK)
		return -1;
	if(in_msg->usr_id < 0){
		out_msg->act_type = RPL_DENY;
		return 0;
	}	
	out_msg->act_type = RPL_LOGIN;
	for(i = 0; i<tickets->len; i++){
		if(in_msg->ticket_id == tics[i].id){
			out_msg->time_start = tics[i].time;
			out_msg->ticket_id = tics[i].id;
			strcpy(out_msg->train_no, tics[i].trainno);
			out_msg->ticket_count = in_msg->ticket_count;
			strcpy(out_msg->other, tics[i].description);
			if(tics[i].num <= 0){
				out_msg->order_no = NO_TICKET;
				return 0;
			}else if (tics[i].num<in_msg->ticket_count){
				out_msg->order_no = LACK_TICKET;
				out_msg->ticket_count = tics[i].num;
				return 0;
			}else{
				tics[i].num -=out_msg->ticket_count;
				out_msg->order_no = order_no++;
				return 0;
			} 
		}	
	}		
	out_msg->order_no = NO_TICKET;
	return 0;
}

static int query_booking(protocol_t *in_msg, protocol_t* out_msg){
	if(in_msg == NULL || out_msg == NULL ||in_msg->act_type != ASK_QUERY_BOOKING)
		return -1;
	if(in_msg->usr_id < 0){
		out_msg->act_type = RPL_DENY;
		return 0;
	}
	return 0;
}

static int end_session(protocol_t *in_msg, protocol_t* out_msg){
	return 0;
}

